package org.sixtynine.stock.controller;

import java.util.List;

import javax.validation.Valid;

import org.sixtynine.stock.Constants.CommonData;
import org.sixtynine.stock.dto.GridPramDTO;
import org.sixtynine.stock.dto.Page;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.Filter;
import org.sixtynine.stock.entity.FilterCategory;
import org.sixtynine.stock.entity.Module;
import org.sixtynine.stock.model.LoadingSearchCriteria;
import org.sixtynine.stock.service.FilterService;
import org.sixtynine.stock.service.GenericService;
import org.sixtynine.stock.service.content.DataManagerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Thilan
 * 
 */
@Controller
@SessionAttributes
public class FilterController {

	/** TODO configure */
	private int RECORDS_PER_PAGE = 10;

	@Autowired
	private GenericService genericService;

	@Autowired
	DataManagerService dataManagerService;

	@Autowired
	FilterService filterService;

	@RequestMapping(value = "/admin/filter/search")
	public ModelAndView search(@ModelAttribute LoadingSearchCriteria criteria) {
		ModelAndView modelAndView = new ModelAndView("/admin/filter/list");
		loadData(1, -1, criteria.getFilterCategoryId(), modelAndView, criteria);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/filter/add")
	public ModelAndView addFilter() {
		ModelAndView modelAndView = new ModelAndView("/admin/filter/add");
		modelAndView.addObject("filter", new Filter());

		List<BaseEntity> filterCategory = genericService
				.findAll(FilterCategory.class);
		List<BaseEntity> module = genericService.findAll(Module.class);

		modelAndView.addObject("filterCategoriesMap", filterCategory);
		modelAndView.addObject("moduleMap", module);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/filter/add/process")
	public ModelAndView addingFilter(@ModelAttribute @Valid Filter filter,
			BindingResult result) {
		ModelAndView modelAndView = null;
		if (!result.hasErrors()) {
			genericService.saveOrUpdate(filter);

			modelAndView = new ModelAndView("/admin/filter/list");

			List<BaseEntity> filterList = genericService.findAll(Filter.class);
			modelAndView.addObject("filterList", filterList);

			String message = "Filter was successfully added.";
			modelAndView.addObject("message", message);

		} else {
			modelAndView = new ModelAndView("/admin/filter/add");

			List<BaseEntity> filterCategory = genericService
					.findAll(FilterCategory.class);
			List<BaseEntity> module = genericService.findAll(Module.class);

			modelAndView.addObject("filterCategoriesMap", filterCategory);
			modelAndView.addObject("moduleMap", module);

		}

		loadData(1, -1, filter.getFilterCategory().getId(), modelAndView, null);
		return modelAndView;
	}

	@RequestMapping(value = "/admin/filter/list")
	public ModelAndView listOfFilters(
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "totalRecords", required = false) Integer totalRecords) {
		ModelAndView modelAndView = new ModelAndView("/admin/filter/list");
		loadData(page, totalRecords, -1, modelAndView, null);

		return modelAndView;
	}

	/**
	 * load data
	 * 
	 * @param page
	 * @param totalRecords
	 * @param companyId
	 * @param fromDate
	 * @param toDate
	 * @param modelAndView
	 */
	private void loadData(Integer page, Integer totalRecords,
			int filterCategoryId, ModelAndView modelAndView,
			LoadingSearchCriteria criteria) {
		GridPramDTO gridPramDTO = new GridPramDTO();
		gridPramDTO.setRows(RECORDS_PER_PAGE);
		if (page != null) {
			gridPramDTO.setPage(page);
		} else {
			gridPramDTO.setPage(1);
		}
		if (totalRecords != null) {
			gridPramDTO._setTotalNumberOfRecords(totalRecords);
		}

		Page<Filter> filterPage = filterService.searchFilter(filterCategoryId,
				gridPramDTO);
		modelAndView.addObject("filterPage", filterPage);

		List<BaseEntity> categories = dataManagerService
				.getData(CommonData.FILTER_CATEGORY.toString());

		modelAndView.addObject("categoryMap", categories);
		if (criteria == null) {
			criteria = new LoadingSearchCriteria();

			criteria.setFilterCategoryId(filterCategoryId);
		}
		modelAndView.addObject("criteria", criteria);

	}

	@RequestMapping(value = "/admin/filter/edit/{id}", method = RequestMethod.GET)
	public ModelAndView editFilter(@PathVariable Integer id) {
		ModelAndView modelAndView = new ModelAndView("/admin/filter/edit");
		BaseEntity filter = genericService.findById(id, Filter.class);

		List<BaseEntity> filterCategory = genericService
				.findAll(FilterCategory.class);
		List<BaseEntity> module = genericService.findAll(Module.class);

		modelAndView.addObject("filterCategoriesMap", filterCategory);
		modelAndView.addObject("moduleMap", module);
		modelAndView.addObject("filter", filter);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/filter/edit/{id}", method = RequestMethod.POST)
	public ModelAndView edditingTeam(@ModelAttribute @Valid Filter filter,
			BindingResult result, @PathVariable Integer id) {

		if (!result.hasErrors()) {
			genericService.saveOrUpdate(filter);
			ModelAndView modelAndView = new ModelAndView("/admin/filter/list");

			List<BaseEntity> filterList = genericService.findAll(Filter.class);
			modelAndView.addObject("filterList", filterList);

			loadData(1, -1, filter.getFilterCategory().getId(), modelAndView,
					null);

			String message = "Filter was successfully edited.";
			modelAndView.addObject("message", message);

			return modelAndView;
		} else {
			ModelAndView modelAndView = new ModelAndView("/admin/filter/edit");

			List<BaseEntity> filterCategory = genericService
					.findAll(FilterCategory.class);
			List<BaseEntity> module = genericService.findAll(Module.class);

			modelAndView.addObject("filterCategoriesMap", filterCategory);
			modelAndView.addObject("moduleMap", module);
			modelAndView.addObject("filter", filter);

			return modelAndView;
		}
	}

	@RequestMapping(value = "/admin/filter/delete/{id}", method = RequestMethod.GET)
	public ModelAndView deleteFilter(@PathVariable Integer id) {
		genericService.delete(id, Filter.class);
		ModelAndView modelAndView = new ModelAndView("/admin/filter/list");

		loadData(1, -1, -1, modelAndView, null);

		List<BaseEntity> filterList = genericService.findAll(Filter.class);
		modelAndView.addObject("filterList", filterList);
		String message = "Filter was successfully deleted.";
		modelAndView.addObject("message", message);
		return modelAndView;
	}

}
